package miniworld;

import homeMadeExceptions.NotYetImplementedException;
import metric.CentralObservableUnit;
import simulationEngine.SimulationEngine;
import datatypes.BluetoothDeviceAddress;
import datatypes.Host;
import datatypes.Message;

public class RoutingNetworkApi {

	private Host host = null;

	
	public RoutingNetworkApi (Host host) {
		this.host = host;
	}
	
	public void enableDiscoveryMechanism (){
		//Write Metric
		int tmp = SimulationEngine.getEngine(host.getSimulationEngineID()).getSimulationEnviroment().getClock().getCurrentTime();
		CentralObservableUnit.discoveryServiceEnabled(host, tmp);
		//-->call Routing Protocol Enable
		host.getRoutingSocket().enableBluetoothDevice();
	}

	public void disableDiscoveryMechanism () {
		//Write Metric
		int tmp = SimulationEngine.getEngine(host.getSimulationEngineID()).getSimulationEnviroment().getClock().getCurrentTime();
		CentralObservableUnit.discoveryServiceDisabled(host, tmp);
		//-->call Routing Protocol Disable
		host.getRoutingSocket().disableBluetoothDevice();
	}
	
	
	protected void invokeSendMessage (Message msg, BluetoothDeviceAddress target) {
		//Write Metric
		int tmp = SimulationEngine.getEngine(host.getSimulationEngineID()).getSimulationEnviroment().getClock().getCurrentTime();
		if (target == null){
			CentralObservableUnit.discoveryServiceSendMessage(host, "broadcast", msg, tmp);	
		} else {
			CentralObservableUnit.discoveryServiceSendMessage(host, target.getFirstPart(), msg, tmp);			
		}
		//-->call Routing Protocol SendMessage
		host.getRoutingSocket().invokeSendMessage(msg, target);
	}
	
	public void onReceiveMessage (Message msg, BluetoothDeviceAddress source){
		//Write Metric
		int tmp = SimulationEngine.getEngine(host.getSimulationEngineID()).getSimulationEnviroment().getClock().getCurrentTime();
		CentralObservableUnit.discoveryServiceReceiveMessage(host, source.getFirstPart(), msg, tmp);
		//-->call Discovery Protocol onReceiveMsg
		try {
			host.getDiscoverySocket().receiveMessage(msg, source);
		} catch (NotYetImplementedException e) {
			e.printStackTrace();
		}
	}
	
	//an Message could not be send to target (or it is not clear if it could be send)
	public void invokeMessageLost (Message msg, BluetoothDeviceAddress target){
		//TODO:LOG?
		//-->call Discovery Protocol onReceiveMsg
		try {
			host.getDiscoverySocket().onMessageLost(msg, target);
		} catch (NotYetImplementedException e) {
			e.printStackTrace();
		}
	}
	
	//the Ack that an Sended Message has Received
	public void invokeAckForSendedMessage(Message msg, BluetoothDeviceAddress target){
		//TODO:LOG?
		//-->call Discovery Protocol onReceiveMsg
		try {
			host.getDiscoverySocket().onMessageACK(msg, target);
		} catch (NotYetImplementedException e) {
			e.printStackTrace();
		}
	}
	
	public void newConnectionEstablished(BluetoothDeviceAddress remoteHost){
		//TODO:LOG?
		try {
			this.host.getDiscoverySocket().onConnectionEstablished(remoteHost);
		} catch (NotYetImplementedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
